/*
 * @Author: sunkaiyuan 
 * @Date: 2021-10-23 11:05:13 
 * @Last Modified by: sunkaiyuan
 * @Last Modified time: 2021-12-01 16:35:05
 */


(function ($, window, document, undefined) {
  'use strict'
  var fs = function (string, param) {
    var arg, i;
    length = param.length;

    for (i = 0; i < length; i++) {
      if (typeof param[i] == 'object')
        arg = JSON.stringify(param[i]);
      else
        arg = param[i];
      eval("string = string.replace(/\\{" + i + "\\}/g,'" + arg + "')");

      // string = string.replace(/"{"+i+"}"/g, arg)
      // string = str_replace("{" + $i + "}", arg, string);
    }

    return string;
  }

  function __autoWidthHeight(options) {

    var __autowidth = options.autowidth;
    var __autoheight = options.autoheight;
    var __footerrow = options.footerrow;
    var __filterToolbar = options.filterToolbar;
    var __groupHeader = options.groupHeader;
    var __caption = options.caption;
    var __height = options.height;
    var __width = options.width;
    if (__autowidth) {
      var parent = $(options.grid).parent().parent().parent().parent().parent();
      var parentwidth = parent.length ? parent.width() : $(window).width();
      __width = parentwidth - 2;
    }
    if (__autoheight) {
      var parentheight = $(window).height();
      var cardbodypadding = $(".card-body").length ? $(".card-body").innerHeight() - $(".card-body").height() : 0;
      //工具栏
      var __toolbarHeight = $(".nr-toolbar").length ? $(".nr-toolbar").outerHeight() : 0;
      //搜素框

      var __formHeight = $(".nr-form").length ? $(".nr-form").outerHeight() : 0;
      __formHeight += $(".nr-other").length ? $(".nr-other").outerHeight() : 0;

      //其他偏移计算，合计页脚
      var __offsetHeight = __footerrow != 0 ? (__footerrow != 1 ? 46 : 28) : 0;

      //筛选搜素框，没有就设置表头，有，就表头26+搜素框31
      __offsetHeight += __filterToolbar == true ? 62 : 28;

      //合并表头
      __offsetHeight += __groupHeader == true ? 28 : 0;

      //有没有翻页
      __offsetHeight += $(".ui-pager-control").length > 0 ? $(".ui-pager-control").outerHeight() : 0;
      // console.log(__offsetHeight+__toolbarHeight);
      // console.log($(".ui-pager-control").length > 0 ? $(".ui-pager-control").outerHeight() : 0);
      //用card tab 选择 设置。
      __offsetHeight += $(".card").length ? parseInt($('.card').css('marginBottom')) : 0;
      __offsetHeight += $(".card-header").length ? $(".card-header").outerHeight() : 0;

      __height = parentheight - __toolbarHeight - __formHeight - __offsetHeight - cardbodypadding - 3;

    }

    return [parseInt(__width, 10), (parseInt(__height, 10))];
  }

  //grid init
  var Initgrid = function (elem, opts) {
    this.elem = $(elem);
    this.options = $.extend({}, this.defaults, $.fn.initgrid.defaults, opts);
    this.version = 'v1.0.0';
    this.init(this.options);
  }
  // $config = [], $id = 'jqgrid', $url = CURRENT_URL, $toolbarClass = 'nr-toolbar', $widthReference = '', $excludetoolbarheight = false
  Initgrid.prototype = {
    init: function (options) {
      var id,
        groupHeader = false,
        pager = false,
        hasNavGrid, navGrid, that = this,

        groupHeadersOption = options.groupHeaders, sortableRows, toolbarjs;
      if (options.groupHeaders)
        groupHeader = true;
      pager = pager == true ? true : false;
      if (options.navGrid) {
        hasNavGrid = false;
        navGrid = '{}';
      } else {
        hasNavGrid = true;
        navGrid = options.navGrid;
      }
      if (options['id']) id = options['id']; else id = 'jqgrid';

      var table = $("<table id=" + id + "></table>\n\t");
      var page = $("<div id=" + id + "_pager></div>\n\t");
      this.elem.append(table);
      this.elem.append(page);
      $.each(options.colModel, function (key, value) {
        $.each(value, function (k, v) {

          if (typeof (v) == "string") {
            if (v.substr(0, 1) == "{" || v.substr(0, 8) == "function") {
              options.colModel[key][k] = eval("(" + v + ")");
            } else if (v.substr(0, 10) == "formatter." || v.substr(0, 9) == "unformat.") {
              options.colModel[key][k] = eval(v);
            } else if (k.substr(0, 11) == "editoptions") {
              //修改下拉菜单的时候  使用
              options.colModel[key][k] = eval(v);
              // $columnOption += "\"{$key}\":{value:\"{$val['value']}\"}";
            }
          }
        })

      })

      if (typeof (options['ondblClickRow']) == "string") {
        options['ondblClickRow'] = eval("(" + options['ondblClickRow'] + ")");
      }

      $.each(options, function (key, v) {
        if (typeof (v) == "string") {
          if (v.substr(0, 1) == "{" || v.substr(0, 8) == "function") {
            options[key] = eval("(" + v + ")");
          }
        }
      })

      this.options.grid = table.jqGrid({
        url: options.url,
        datatype: "json",
        treeGrid: options.treeGrid,
        expandColumn: options.expandColumn,
        treedatatype: "json",
        treeGridModel: 'adjacency',
        treeReader: {
          loaded: "loaded",
          icon_field: "icon_class",
          leaf_field: "isLeaf",
          level_field: "level",
          expanded_field: "expanded",
          parent_id_field: "parent_id"
        },
        ExpandColClick: true,
        mtype: "POST",
        sortname: options.sortname,
        sortorder: options.sortorder,
        forcePage: options.forcePage,
        columnSortable: options.columnSortable,
        rownumbers: options.rownumbers,
        autowidth: options.autowidth,
        width: __autoWidthHeight(options)[0],
        height: __autoWidthHeight(options)[1],
        width: options.width,
        height: options.height,
        rownumWidth: options.rownumWidth,
        sortable: options.sortable,
        multiselect: options.multiselect,
        multiselectWidth: options.multiselectWidth,
        multiboxonly: options.multiboxonly,
        multikey: options.multikey,
        subGrid: options.subGrid,
        subGridRowExpanded: options.subGridRowExpanded,
        subGridOptions: {
          reloadOnExpand: true,
        },
        shrinkToFit: options.shrinkToFit,
        frozenColumns: options.frozenColumns,
        autoload: options.autoload,
        rowList: options.rowList,
        pgbuttons: options.pgbuttons,
        pginput: options.pginput,
        pager: options.pager == true ? id + "_pager" : "",
        pagerpos: options.pagerpos,
        recordpos: options.recordpos,
        viewrecords: options.viewrecords,
        altRows: options.altRows,
        hoverrows: options.hoverrows,
        colModel: options.colModel,
        toolbar: [false, ""],
        cellEdit: options.cellEdit,
        cellurl: options.cellurl,
        navkeys: options.navkeys,
        hidegrid: options.hidegrid,
        loadonce: options.loadonce,
        footerrow: options.footerrow,
        userDataOnFooter: options.userDataOnFooter,
        caption: options.caption,
        scroll: options.scroll,
        resetsearch: options.resetsearch,
        onSelectRow: options.onSelectRow,
        beforeSelectRow: options.beforeSelectRow,
        onSelectAll: options.onSelectAll,
        onContextCallBack: options.onContextCallBack,
        ondblClickRow: options.ondblClickRow,
        beforeProcessing: options.beforeProcessing,
        loadError: function (xhr, status, error) {
          // sy.responseHandle(xhr);
        },
        errorCell: function (xhr, status, error) {
          // sy.responseHandle(xhr);
        },
        afterSubmitCell: function (data) {
          // parent.sy.tip(data.message, data.success);
        },
        knv: false,
        loadComplete: options.loadComplete,
        gridComplete: options.gridComplete,
      });
      sortableRows == true ? table.jqGrid("sortableRows") : "";
      hasNavGrid && $("#" + id).jqGrid("navGrid", "#" + id + "_pager", options.navGrid);
      options.filterToolbar && $("#" + id).jqGrid("filterToolbar");
      toolbarjs && $("." + options.toolbarClass).toolbar();
      groupHeader && table.setGroupHeaders({
        useColSpanStyle: true,
        groupHeaders: groupHeadersOption
      })


      $(window).on("resize.grid", function () {
        setTimeout(function () {
          that.options.grid.setGridWidth(__autoWidthHeight(options)[0]);
          that.options.grid.setGridHeight(__autoWidthHeight(options)[1]);
        }, 100);
      })
    }


  };
  Initgrid.prototype.funcs = {

  };
  $.fn.initgrid = function (options) {
    if (typeof options == 'string') {
      var args = arguments,
        grid = this.data('grid'),
        func = sidebar[grid];
      Array.prototype.shift.call(args);
      func && func.apply(grid, args);
      return this;
    }

    return this.each(function () {
      if (!$.data(this, 'grid')) {
        $.data(this, 'grid', new Initgrid(this, options));
      }
    });
  };
  $.fn.initgrid.defaults = {

    'subGrid': false,
    'forcePage': false, // 是否显示列序号
    'rownumbers': true, // 是否显示列序号
    'autowidth': true, // 自动宽
    'sortable': true, // 列拖动, 左右排序
    'columnSortable': true, // 列点击 上下排序 总控制
    'height': "full",
    'autoheight': true,
    'width': 500,
    'rownumWidth': 35, // 列序号宽度datatype''
    'multiselectWidth': 25,
    'multiselect': true, // 是否多选
    'multiboxonly': true, // 选中行选中checkbox
    'multikey': false, // 多选快捷键
    'shrinkToFit': false,
    'frozenColumns': false,
    'filterToolbar': false, // 搜索栏
    'autoload': false,
    'sortname': 'id', // 默认的排序列名
    'sortorder': 'desc', // 默认的排序方式（asc升序，desc降序）
    'rowNum': 20, // 每页行数
    'rowList': [10, 20, 40, 80], // 每页行数下拉列表
    'navGrid': {},
    'pginput': true,
    'onContextCallBack': false,
    'pgbuttons': true,
    'pagerpos': "center",
    'recordpos': "right",
    'viewrecords': true, // 是否在浏览导航栏显示记录总数
    'resetsearch': true,
    'treeGrid': false,
    'toolbar': "[false, 'top']",
    'toolbarjs': true, // 初始化插件toolbar
    'pager': true,
    'altRows': true, // 设置为交替显示行表格,默认为false
    'cellEdit': false, // 单元格编辑
    'cellurl': "edit", // 单元格保存url
    'navkeys': "[true, 38, 40]", // 键盘控制修改单元格
    'hidegrid': false, // torggle grid的按钮
    'loadonce': false, // 加载一次
    'hoverrows': true, // 鼠标悬停颜色变化
    'caption': "",
    'expandColumn': "name",
    'footerrow': 0,
    'userDataOnFooter': 1,
    'scroll': false,
    'subGridRowExpanded': 'custom.subGridRowExpanded',
    'onSelectRow': true,
    'beforeSelectRow': true,
    'onSelectAll': true,
    'ondblClickRow': true,
    'gridComplete': true,
    'loadComplete': true,
    'beforeProcessing': true,
    'formctrl': 1,
    'colModel': [],
    'editrules': [],
    'groupHeaders': [],
    'sortableRows': false, // 行拖动排序
  };
  var InitgridEdit = function (elem, opts, name) {
    this.elem = $(elem);
    this.options = $.extend({}, this.defaults, $.fn.initgridEdit.defaults, opts);
    this.version = 'v2.0.0';
    this.name = name;
    this.init();
    var that = this;
    $('a[data-toggle="pill"]').on('shown.bs.tab', function (e) {
      that.options.grid.setGridWidth(__autoWidthHeight(that.options)[0]);
      that.options.grid.setGridHeight(__autoWidthHeight(that.options)[1]);
    })
  }
  InitgridEdit.prototype = {
    init: function () {
      var columnOption = this.options.colModel;
      var data = this.options.data;
      var that = this;
      var table = "<table id=\"" + this.options.id + "\"></table>\n\t";
      var page = "<input type=\"hidden\" class=\"grid-editor posting\" data-grid=\"" + this.options.id + "\" name=\"" + this.name + "\"/>\n\t";
      this.elem.append(table);
      this.elem.append(page);
      $.each(this.options.colModel, function (key, value) {
        $.each(value, function (k, v) {
          if (typeof (v) == "string") {
            if (v.substr(0, 1) == "{" || v.substr(0, 8) == "function") {
              that.options.colModel[key][k] = eval("(" + v + ")");
            } else if (v.substr(0, 10) == "formatter." || v.substr(0, 9) == "unformat.") {
              that.options.colModel[key][k] = eval(v);
            } else if (k.substr(0, 11) == "editoptions") {
              //修改下拉菜单的时候  使用
              that.options.colModel[key][k] = eval(v);
              // $columnOption += "\"{$key}\":{value:\"{$val['value']}\"}";
            }
          }
        })

      })

      this.options.grid = jQuery("#" + this.options.id).jqGrid(
        {
          editurl: "clientArray",
          datatype: "local",
          autoload: false,
          colNames: that.options.colNames,
          rownumbers: that.options.rownumbers,
          autowidth: that.options.autowidth,
          width: that.options.width,
          height: that.options.height,
          multiselect: that.options.multiselect,
          multiboxonly: that.options.multiboxonly,
          subGrid: that.options.subGrid,
          subGridRowExpanded: that.options.subGridRowExpanded,
          subGridOptions: {
            reloadOnExpand: true,
          },
          rownumWidth: that.options.rownumWidth,
          shrinkToFit: that.options.shrinkToFit,
          filterToolbar: that.options.filterToolbar,
          rowNum: 999999,
          hoverrows: that.options.hoverrows,
          viewrecords: that.options.viewrecords,
          colModel: that.options.colModel,
          footerrow: that.options.footerrow,
          hidegrid: that.options.hidegrid,
          caption: that.options.caption,
          columnSortable: that.options.columnSortable,
          userDataOnFooter: true, loadError:
            function (xhr, status, error) { sy.responseHandle(xhr); }
        });

      if (that.options.sortableRows == true)
        that.options.grid.jqGrid("sortableRows");
      $(window).on("resize.grid", function () {
        setTimeout(function () {

          that.options.grid.setGridWidth(__autoWidthHeight(that.options)[0]);
          that.options.grid.setGridHeight(__autoWidthHeight(that.options)[1]);
        }, 100);
      })
    }
  }
  InitgridEdit.prototype.funcs = {

  };
  $.fn.initgridEdit = function (options, name = 'items') {
    if (typeof options == 'string') {
      var args = arguments,
        grid = this.data('gridEdit'),
        func = sidebar[grid];
      Array.prototype.shift.call(args);
      func && func.apply(grid, args);
      return this;
    }

    return this.each(function () {
      if (!$.data(this, 'gridEdit')) {
        $.data(this, 'gridEdit', new InitgridEdit(this, options, name));
        $(window).trigger("resize.grid");
      }
    });
  };
  $.fn.initgridEdit.defaults = {
    'id': "jqgrid_items",
    'mtype': 'POST',
    'colNames': [],
    'filterToolbar': false, // 搜索栏
    'rownumbers': true,
    'autowidth': true,
    'autoheight': true,
    'height': 250,
    'width': 500,
    'rownumWidth': 25,
    'multiselectWidth': 25,
    'multiboxonly': true, // 选中行选中checkbox
    'subGridRowExpanded': 'custom.subGridRowExpanded',
    'multiselect': true,
    'shrinkToFit': false,
    'viewrecords': true,
    'footerrow': false,
    'hoverrows': true, // 鼠标悬停颜色变化
    'caption': "", // 标题
    'hidegrid': false, // torggle grid的按钮
    'sortableRows': false, // 行拖动排序
    'columnSortable': true, // 列点击排序
    'colModel': [],
  }
  //toolbar init
  var Toolbar = function (elem, opts) {
    this.elem = $(elem);


    this.options = $.extend({}, this.defaults, $.fn.sidebar.defaults, opts);
    this.version = 'v2.0.0';
    this.vendor(this.options);
    this.init();
    this.initcontextMenu();
    this.bindEvent();

    this.setGridParam();

    // 初始化 搜索框插件

    var form = this.elem.siblings('.nr-form');
    if (form.length) {
      form.data('grid', this.options.gridId);
      form.formSearch();

      $(this).width(this.grid.width());
    } else {
      var autoload = this.grid.jqGrid('getGridParam', 'autoload');
      if (autoload == false) {
        if (this.grid.data('filterToolbar')) {
          this.grid[0].triggerToolbar && this.grid[0].triggerToolbar();
        } else {
          this.reloadGrid(true);
        }
      }
    }

  }


  Toolbar.prototype = {
    vendor: function (buttons) {

      var linkbutton = "",
        linkbuttonDiv = "",
        contextMenu = "",
        string = "",
        setting;

      linkbutton = "<a class=\"{0} toolbar-btn-plain\" data-select-mode=\"{7}\" data-param=\"{8}\" data-options=\"{1}\" data-status=\"{9}\" data-fstatus=\"{10}\" href=\"javascript:;\" id=\"{6}\" data-func=\"{2}\">";
      linkbutton += "<span class=\"fas {3}\">&nbsp;</span><span class=\"toolbar-btn-left\">{4}{5}</span>";
      linkbutton += "</a>\n\t";

      linkbuttonDiv = "<div>";
      linkbuttonDiv += "<span class=\"fas {3}\">&nbsp;</span><span   class=\"toolbar-btn-left\">{4}{5}</span>";
      linkbuttonDiv += "</div>\n\t";

      $.each(buttons, function (key, val) {
        formattertring = "";
        if (typeof val != 'object') {
          key = val;
          val = {};
        }
        setting = { opt: '', mode: '', func: '', param: {}, icon: "fa-" + key, 'text': key, status: false, fstatus: false, RM: false };

        if (key.text)
          setting['text'] = key.text;
        if (key.icon)
          setting['icon'] = key.icon;

        $.extend(setting, val);
        var m = "", dr, mstr, ds;
        if (setting['menu'] == true) {
          m = "menu:'#menu_" + $key + "',";
          setting['func'] = '';
          dr = "<span class=\"toolbar-btn-downarrow\">&nbsp;</span>";
          mstr = "menubutton";
        }
        else {
          m = "";
          dr = "";
          mstr = "linkbutton";

          if (setting['func'] == '') {
            setting['func'] = key;
          }
        }
        var mode;
        if (setting['mode'] == '') {
          if ($.inArray(key, ['edit', 'copy', 'browser', 'storage', 'pack', 'detail', 'notice', 'logistic_detail',]) >= 0) {
            mode = 'single';

          } else if ($.inArray(key, ['faudit', 'fnoaudit', 'return', 'ok', 'remove', 'delete', 'audit', 'recovery', 'abrogate', 'noaudit', 'complete', 'nocomplete', 'recover', 'posting', 'redpunch', 'printer_detail', 'weixin', 'color', 'download', 'logistic']) >= 0) {
            mode = 'multiple';
          } else {
            mode = 'none';

          }
        } else {
          mode = setting['mode'];
        }

        if (mode == 'single') {
          ds = 'disabled:true';
        } else if (mode == 'multiple') {
          ds = 'disabled:true';
        } else {
          ds = 'disabled:false';
        }

        if (setting['disabled'] == true) {
          ds = "disabled:true";
        }
        setting['opts'] = m + ds;
        var formattertring;
        if (setting['type'] != 'html')
          formattertring = fs(
            linkbutton,
            [mstr,
              setting['opts'],
              setting['func'],
              setting['icon'],
              setting['text'],
              dr,
              "linkbutton_" + key,
              mode,
              setting['param'],
              setting['status'],
              setting['fstatus']]
          );
        else {
          formattertring = fs(
            linkbuttonDiv,
            [mstr,
              setting['opts'],
              setting['func'],
              setting['icon'],
              setting['text'],
              dr,
              "linkbutton_" + ey,
              mode,
              setting['param'],
              setting['status'],
              setting['fstatus']]
          );
        }

        if (setting['RM'] != 'just')
          string += formattertring;
        if (setting['RM'] == true || setting['RM'] == 'just') {
          contextMenu += "<li>" + formattertring + "</li>";
        }
        if (val['separator'] == true) {
          if (val['RM'] != 'just')
            string += "<div class=\"separator\"></div>\n\t";
          if (val['RM'] == true || val['RM'] == 'just')
            contextMenu += "<li class='li_separate'></li>";
          return true;
        }
      })


      if (contextMenu != '')
        contextMenu = "<div class=__JGcontextMenu id=" + rand() + " style='display: none'><ul>" + contextMenu + " </ul> </div>";
      this.elem.append(contextMenu + string)
      // this.elem.toolbar();
      // return contextMenu + string;
      //------------------end
    },

    init: function () {
      var that = this,
        elem = that.elem,
        opts = that.options;

      // 保存 jqgrid ID
      opts.gridId = elem.data('grid') || 'jqgrid';
      that.grid = $('#' + opts.gridId);

      if (!elem.hasClass('nr-toolbar')) {
        console.error('工具栏缺少类属性(nr-toolbar)');
      }

      if (that.grid.length == 0) {
        console.log('没有找到grid对象');
      }
    },
    initcontextMenu: function () {
      var grid = this.grid,
        elem = this.elem,
        that = this,
        id = elem.find(".__JGcontextMenu").attr('id');
      if (elem.find(".__JGcontextMenu").length > 0) {
        $(grid).parent().parent().contextMenu(id, {
          //重写onContextMenu和onShowMenu事件
          onContextMenu: function (e) { //显示菜单
            var rowId = $(e.target).closest("tr.jqgrow").attr("id"); //获得RowID 
            grid.jqGrid('resetSelection');
            if (rowId) {
              grid.jqGrid('setSelection', rowId);
            } else {
              var toolbarbotton = elem.find("a");
              toolbarbotton.each(function () {
                var a = $(this);
                var disabeldata = {};
                var options = $.trim(a.attr('data-options'));
                var d;
                ((d = options.substring(0, 1)),
                  (e = options.substring(options.length - 1, 1)),
                  '{' != d && (options = '{' + options),
                  '}' != e && (options += '}'),
                  (disabeldata = new Function('return ' + options)()));
                if (disabeldata.disabled)
                  a.addClass('toolbar-btn-disabled');
              })
            }
            return true;
          },
          onShowMenu: function (e, menu) { //显示菜单
            var options = that.grid.jqGrid('getGridParam')
            if ($.isFunction(options.onContextCallBack))
              onContextCallBack(menu, that);

            return menu;
          },
          menuStyle: { //菜单样式			            
            backgroundColor: '#fcfdfd',
            border: '1px solid #a6c9e2',
            maxWidth: '100px', // to be sure 			           
            width: '100%' // to have good width of the menu 			         
          },
          itemHoverStyle: { //点击菜单上面的样式			          
            border: '1px solid #79b7e7',
            color: '#1d5987',
            backgroundColor: '#d0e5f5',

          }

        })
      };
    },

    bindEvent: function () {
      var that = this,

        elem = this.elem;


      elem.find('.linkbutton,.menu-item').on('click', function () {
        var func = $(this).data('func'),
          param = $(this).attr('data-param') || '[]',
          args = [eval('(' + param + ')')],
          obj = $(this)
            .closest('div.nr-toolbar')
            .data('toolbar');

        if (func == 'delete') {
          func = 'del';
        }

        // 优化条件，不存在对应方法时，使用默认的dispatch方法
        if (!$(this).hasClass('toolbar-btn-disabled')) {
          if ($.isFunction(obj.funcs[func])) {

            obj.funcs[func].apply(obj, args);
          } else {
            args.unshift(func);
            obj.funcs.dispatch.apply(obj, args);
          }
        }
      });
    },
    triggerFunction: function (id, trigger) {
      var that = this,
        elem = this.elem,
        linkbuttonSave = elem.find('#' + id),
        func = linkbuttonSave.data('func'),
        param = linkbuttonSave.attr('data-param') || '[]',
        args = eval('(' + param + ')');

      args.push(trigger);

      return that.funcs[func].apply(that, args);
    },
    setGridParam: function () {
      var that = this,
        grid = that.grid,
        param = {};

      if (grid && grid.length) {
        var _param = grid.jqGrid('getGridParam');

        param['ondblClickRow'] =
          _param.ondblClickRow && $.isFunction(_param.ondblClickRow) ?
            _param.ondblClickRow :
            _param.ondblClickRow ?
              function (rowid, iRow, iCol, e) {
                that.funcs.ondblClickRow.call(that, rowid, iRow, iCol, e);
              } :
              null;

        param['beforeProcessing'] =
          _param.beforeProcessing && $.isFunction(_param.beforeProcessing) ?
            _param.beforeProcessing :
            _param.beforeProcessing ?
              function (data, state, xhr) {
                if (state == 'success') {
                  if (this.p.scroll) {
                    var gridData = $(this).data('gridData') || [];
                    $(this).data('gridData', gridData.concat(data.rows));
                  } else {
                    $(this).data('gridData', data.rows);
                  }
                  this.p.savedRow = []; // 重置单元格编辑的行
                }
              } :
              null;

        param['beforeSelectRow'] =
          _param.beforeSelectRow && $.isFunction(_param.beforeSelectRow) ?
            _param.beforeSelectRow :
            _param.beforeSelectRow ?
              function (rowid, event) {
                that.funcs.beforeSelectRow.call(that, rowid);
              } :
              null;

        param['onSelectRow'] =
          _param.onSelectRow && $.isFunction(_param.onSelectRow) ?
            _param.onSelectRow :
            _param.onSelectRow ?
              function (rowid, state, event) {
                that.funcs.onSelectRow.call(that, rowid, state, event);
                that.check();
              } :
              null;

        param['onSelectAll'] =
          _param.onSelectAll && $.isFunction(_param.onSelectAll) ?
            _param.onSelectAll :
            _param.onSelectAll ?
              function (rowids, state) {
                that.check();
              } :
              null;

        param['gridComplete'] =
          _param.gridComplete && $.isFunction(_param.gridComplete) ?
            _param.gridComplete :
            _param.gridComplete ?
              function () {
                that.check();
              } :
              null;
        param['loadComplete'] =
          _param.loadComplete && $.isFunction(_param.loadComplete) ?
            _param.loadComplete :
            _param.loadComplete ?
              function () { } :
              null;

        grid.jqGrid('setGridParam', param);
      }
    },
    unbindEvent: function () {
      var that = this,
        grid = that.grid,
        elem = this.elem;

      elem.find('.linkbutton').off('click');

      if (grid.length) {
        grid.jqGrid('setGridParam', {
          ondblClickRow: null
        });
      }
    },
    setFuncs: function (newFunctions) {
      if (typeof newFunctions === 'object') {
        this.funcs = $.extend({}, this.funcs, newFunctions);
      }
    },
    setParam: function (newParams, overwrite) {
      var that = this;

      if (that && typeof newParams === 'object') {
        if (overwrite == null) {
          overwrite = false;
        }
        if (overwrite === false) {
          that.options = $.extend({}, that.options, newParams);
        } else {
          $.extend(true, that.options, newParams);
        }
      }
    },
    getRowFullData: function (rowid, key = 'id') {
      var that = this,
        grid = that.grid,
        param = {};
      param[key] = rowid
      var list = grid.data('gridData');

      var find = $.find(list, param);

      return find || {};
    },
    getRowFullDatas: function (rowids, key = "id") {
      var that = this,
        grid = that.grid;

      var list = grid.data('gridData');

      var finds = [];
      if (!key)
        key = "id"
      _(list).forEach(function (value, key1) {

        if (rowids.indexOf(value[key] + "") !== -1) {
          finds.push(value);
        }
      });

      return finds || [];
    },
    reloadGrid: function (current) {
      this.funcs.refresh.call(this, current);
    },
    check: function () {
      var that = this,
        elem = that.elem,
        grid = that.grid,
        rowids = grid.jqGrid('getGridParam', 'selarrrow');
      elem.find('[data-select-mode]').each(function () {
        var mode = $(this).data('select-mode');

        $(this).removeClass('toolbar-btn-disabled');

        if (mode == 'single' && rowids.length != 1) {
          $(this).addClass('toolbar-btn-disabled');
        } else if (mode == 'multiple' && rowids.length == 0) {
          $(this).addClass('toolbar-btn-disabled');
        }

      });
    },
    destroy: function () {
      var that = this,
        elem = this.elem;

      elem.find('.linkbutton').addClass('toolbar-btn-disabled');
      that.unbindEvent();
    }
  }
  Toolbar.prototype.funcs = {

    add: function (param, isParent, status) {
      var that = this,
        rowid = that.grid.jqGrid('getGridParam', 'selrow');

      if (isParent) {
        if (!rowid) {
          return sy.alert('请选择父级记录!');
        }

        param = $.extend({}, {
          id: rowid
        }, param || {});
      } else {
        param = param || {};
      }


      var url = sy.url({
        a: 'add',
        param: param
      });

      var opt = $.extend({
        title: '新增',
        cancel: true,
        // class: "modal-lg",//modal-lg  modal-xl modal-sm
        class: "modal-xl",
        button: [{
          name: '保存继续',
          class: "btn-outline-primary",
          submit: true,
          close: true,
          toolbar: that,
          click: function (e, iframe) {

          },
          callback: function () {

          }
        },]
      },
        {}
      );

      sy.open(url, opt);
    },

    edit: function (rowid, param) {
      var that = this;
      rowid = that.grid.jqGrid('getGridParam', 'selrow');
      param = $.extend({}, {
        id: rowid
      }, param);

      if (!rowid) {
        return sy.tip('请选择要修改的记录!', 'error');
      }

      var url = sy.url({
        a: 'edit',
        param: param
      });

      var opts = {};


      var opts = $.extend({
        title: '新增',
        cancel: true,
        class: "modal-xl",
        height: 400,
        width: 600,
        button: [{
          name: '保存继续',
          class: "btn-outline-primary",
          submit: true,
          close: true,
          toolbar: that,
          click: function (e, iframe) {

          },
          callback: function () {

          }
        },]
      },
        {}
      );

      sy.open(url, opts);
    },

    beforeSelectRow: function (rowid, event) { },
    onSelectRow: function (rowid, state, event) { },
    ondblClickRow: function (rowid, iRow, iCol, e) {
      this.funcs.edit.call(this, rowid);
    },
    browser: function (rowid, param) {
      rowid = rowid || this.grid.jqGrid('getGridParam', 'selrow');
      param = param || $.extend({}, {
        id: rowid
      }, param);

      if (!rowid) {
        return sy.alert('请选择要浏览的记录!');
      }

      var url = sy.url({
        a: 'browser',
        param: param
      });

      var opts = $.extend({
        ok: false,
        cancel: true,
        title: '查看',
        okVal: '查看'
      },
        {}
      );
      sy.open(url, opts);
    },

    del: function (param) {
      var that = this;
      parent.layer.confirm('是否确定删除记录？', {
        icon: 3,
        title: '提示'
      }, function (index) {
        that.funcs.dispatch.call(that, 'delete', param);
        parent.layer.close(index);
      });
    },
    remove: function (param) {
      var that = this;
      parent.layer.confirm('是否确定移除记录？', {
        icon: 3,
        title: '提示'
      }, function (index) {
        that.funcs.dispatch.call(that, 'remove', param);
        parent.layer.close(index);
      });
    },
    dispatch: function (action, param, callback) {
      var that = this,
        opts = that.options,
        url = sy.url(action, param),
        rowids = that.grid.jqGrid('getGridParam', 'selarrrow');

      if (rowids.length == 0) {
        return sy.alert('请选择要操作的记录!');
      }

      sy.mask();
      // function (url, data, success, async, error)
      sy.post(
        url,
        {
          'ids[]': rowids
        },
        function (data, textStatus, xhr) {
          parent.sy.tip(data.message, data.success);
          sy.unmask();
          if (data.success) {
            that.reloadGrid();
            if ($.isFunction(callback)) {
              callback(data);
            }
            if ($.isFunction(opts.complete)) {
              opts.complete.call(that, data);
            }
          }
        },
        true,
        function (xhr) {
          sy.responseHandle();
        }
      );
    },

    expand: function (type = 'single', action = 'expand') {
      var that = this;
      var rowid = that.grid.jqGrid('getGridParam', 'selrow');

      if (false) {
        var record = that.grid.jqGrid('getRowData', rowid, true);
        if (record.isLeaf) {
          return;
        }

        that.grid.jqGrid(action + 'Row', record);
        that.grid.jqGrid(action + 'Node', record);

        var childRows = that.grid.jqGrid('getNodeChildren', record);
        for (var i = 0; i < childRows.length; i++) {
          that.grid.jqGrid(action + 'Row', childRows[i]);

          if (!childRows[i]['isLeaf']) {
            that.grid.jqGrid(action + 'Node', childRows[i]);
          }
        }
      } else {
        var root = that.grid.jqGrid('getRootNodes');

        if (type === 'single') {
          var childRows = that.grid.jqGrid('getNodeChildren', root[0]);

          for (let i = 0; i < childRows.length; i++) {
            that.grid.jqGrid(action + 'Row', childRows[i]);

            if (!childRows[i]['isLeaf']) {
              that.grid.jqGrid(action + 'Node', childRows[i]);
            }
          }
        } else if (type === 'multiple') {
          for (var i = 0; i < root.length; i++) {
            var childRows = that.grid.jqGrid('getNodeChildren', root[i]);
            // 根节点的折叠和展开
            that.grid.jqGrid(action + 'Row', root[i]);

            if (!root[i]['isLeaf']) {
              that.grid.jqGrid(action + 'Node', root[i]);
            }
            for (var j = 0; j < childRows.length; j++) {
              that.grid.jqGrid(action + 'Row', childRows[j]);

              if (!childRows[j]['isLeaf']) {
                that.grid.jqGrid(action + 'Node', childRows[j]);
              }
            }
          }
        }
      }
    },
    collapse: function (param) {
      this.funcs.expand.call(this, param, 'collapse');
    },
    cellEditSwtich: function () {
      var that = this,
        opts = that.options,
        elem = that.elem;
      var cellEdit = that.grid.jqGrid('getGridParam', 'cellEdit');
      var button = elem.find('#linkbutton_cellEditSwtich');
      var param = button.attr('data-param');

      var openButton =
        '<span class="fas fa-cellEditSwtich">&nbsp;</span><span class="toolbar-btn-left">开启编辑</span>';
      var closeButton =
        '<span class="fas fa-cellEditClose">&nbsp;</span><span class="toolbar-btn-left">关闭编辑</span>';

      if (param == '[]' || param == "['true']") {
        open();
        button.attr('data-param', "['false']");
        button.html(closeButton);
      } else {
        close();
        button.attr('data-param', "['true']");
        button.html(openButton);
      }

      function open() {
        if (cellEdit) {
          parent.layer.msg('表格编辑已开启！', {
            icon: 8,
            time: 1000
          });
        } else {
          that.grid
            .jqGrid('setGridParam', {
              cellEdit: true,
              beforeSubmitCell: function (rowid) {
                var rowdata = that.getRowFullData(rowid);
                return rowdata.fk_ ? {
                  fk_: rowdata.fk_
                } : null;
              },
              validateEditCell: function (rowid, name) {
                var rowdata;
                if (rowid) {
                  rowdata = that.getRowFullData(rowid);
                  if (
                    $.isFunction(opts.beforeEditCell) &&
                    false !== opts.beforeEditCell.call(that, rowdata, name)
                  ) {
                    return true;
                  } else {
                    return false;
                  }
                } else {
                  return false;
                }
              }
            })
            .trigger('reloadGrid');
          parent.layer.msg('表格编辑开启成功！', {
            icon: 1,
            time: 1000
          });
        }
      }

      function close() {
        if (cellEdit) {
          that.grid
            .jqGrid('setGridParam', {
              cellEdit: false,
              beforeSubmitCell: null,
              validateEditCell: null
            })
            .trigger('reloadGrid');
          parent.layer.msg('表格编辑关闭成功！', {
            icon: 1,
            time: 1000
          });
        } else {
          parent.layer.msg('表格编辑已关闭！', {
            icon: 8,
            time: 1000
          });
        }
      }
    },
    batchEditRow: function (rowid) {
      var that = this,
        opts = that.options,
        grid = that.grid,
        selectrows = grid.jqGrid('getGridParam', 'selarrrow'),
        allrows = grid.jqGrid('getDataIDs'),
        rowids = rowid ? [rowid] : selectrows.length ? selectrows : allrows;

      var rowdatas = that.getRowFullDatas(rowids);
      _.each(rowdatas, function (rowdata) {
        if ($.isFunction(opts.beforeBatchEditRow) && false === opts.beforeBatchEditRow.call(that, rowdata)) {
          return true;
        }

        grid.jqGrid('editRow', rowdata.id);
      });
    },
    batchSaveRow: function (action, param, trigger) {
      var that = this,
        opts = that.options,
        grid = that.grid,
        rowids = grid.jqGrid('getDataIDs'),
        postData = [],
        data = {
          success: false
        },
        result = true,
        url, _A_;

      url = sy.url(action || _A_, param || {});

      _.each(rowids, function (rowid) {
        var ind = grid.jqGrid('getInd', rowid, true);
        var editable = $(ind).attr('editable') || '0';
        var $t = grid.get(0);
        var tmp = {};
        var tmp2 = {};

        if (editable === '1') {
          $('td[role="gridcell"]', ind).each(function (i) {
            var cm = $t.p.colModel[i],
              nm = cm.name;

            if (
              nm !== 'cb' &&
              nm !== 'subgrid' &&
              cm.editable === true &&
              nm !== 'rn' &&
              !$(this).hasClass('not-editable-cell')
            ) {
              nm = cm.editname || nm;
              switch (cm.edittype) {
                case 'checkbox':
                  var cbv = ['Yes', 'No'];
                  if (cm.editoptions && cm.editoptions.value) {
                    cbv = cm.editoptions.value.split(':');
                  }
                  tmp[nm] = $('input', this).is(':checked') ? cbv[0] : cbv[1];
                  break;
                case 'text':
                case 'password':
                case 'textarea':
                case 'button':
                  tmp[nm] = $('input, textarea', this).val();
                  break;
                case 'select':
                  if (!cm.editoptions.multiple) {
                    tmp[nm] = $('select option:selected', this).val();
                    tmp2[nm] = $('select option:selected', this).text();
                  } else {
                    var sel = $('select', this),
                      selectedText = [];
                    tmp[nm] = $(sel).val();
                    if (tmp[nm]) {
                      tmp[nm] = tmp[nm].join(',');
                    } else {
                      tmp[nm] = '';
                    }
                    $('select option:selected', this).each(function (i, selected) {
                      selectedText[i] = $(selected).text();
                    });
                    tmp2[nm] = selectedText.join(',');
                  }
                  if (cm.formatter && cm.formatter === 'select') {
                    tmp2 = {};
                  }
                  break;
                case 'custom':
                  try {
                    if (cm.editoptions && $.isFunction(cm.editoptions.custom_value)) {
                      tmp[nm] = cm.editoptions.custom_value.call(
                        $t,
                        $('.customelement', this),
                        'get'
                      );
                      if (tmp[nm] === undefined) {
                        throw 'e2';
                      }
                    } else {
                      throw 'e1';
                    }
                  } catch (e) {
                    console.error(e);
                  }
                  break;
              }
            }
          });

          postData.push(tmp);
        }
      });

      if (postData.length) {
        sy.post(
          url, {
          batchs: JSON ? JSON.stringify(postData) : '[]'
        },
          function (_data) {
            // 手动调用的时候, 触发问题
            if (_data.success == false) {
              parent.sy.tip(_data.message, _data.success);
            } else {
              false !== trigger && parent.sy.tip(_data.message, _data.success);
            }

            data = _data;
            result = data.success;
          },
          false,
          function (_data) {
            result = _data.success;
          }
        );
      }

      if ($.isFunction(opts.afterBatchSaveRow)) {
        data.trigger = trigger;
        opts.afterBatchSaveRow.call(that, data);
      }

      return result;
    },

    reload: function () {
      window.location.reload();
    },
    refresh: function (current) {
      if (current !== false) {
        this.grid.trigger('reloadGrid', [{
          current: true,
          datatype: 'json'
        }]);
      } else {
        this.grid.trigger('reloadGrid', [{
          datatype: 'json'
        }]);
      }
    }
  }

  //toolbar init
  var ToolbarEdit = function (elem, opts) {

    this.elem = $(elem);

    this.grid = $('#' + (this.elem.data('grid') || 'jqgrid_items'));

    this.totalData = {};
    this.totalTimer = null;
    this.options = $.extend({}, this.defaults, $.fn.toolbarEdit.defaults, opts);
    this.version = 'v2.0.0';
    this.vendor();
    this.init();
    this.initcontextMenu();
    this.bindEvent();
    if (this.grid[0].p.filterToolbar) {
      this.grid.jqGrid('filterToolbar', { stringResult: true, searchOnEnter: false });
    }
  }
  ToolbarEdit.prototype = {
    vendor: function () {
      var linkbutton = "<a class=\"{0} toolbar-btn-plain {4}\" data-func=\"{4}\" data-param=\"{6}\" href=\"javascript:;\" {5} tabindex=\"-1\">";
      linkbutton += "<span class=\"fas {1}\">&nbsp;</span><span class=\"toolbar-btn-left\">{2}{3}</span>";
      linkbutton += "</a>\n\t";
      var contextMenu = "";
      var string = "";
      var downarrow = "";
      var type = "", icon = "", text = "", func = "", param = "";
      if (this.options.toolbar.isMenubutton) {
        downarrow = "<span class=\"toolbar-btn-downarrow\">&nbsp;</span>";
      }

      $.each(this.options.toolbar, function (key, val) {
        var formattertring = "",
          setting = { param: [], icon: "fa-" + key, 'text': key, RM: false };

        setting = $.extend({}, setting, val);

        if (setting.menu == true) {
          downarrow = "<span class=\"toolbar-btn-downarrow\">&nbsp;</span>";
          type = "menubutton";
        }
        else {
          downarrow = "";
          type = "linkbutton";
        }

        icon = setting['icon'];
        text = setting['text'];
        func = setting['func'] == '' || typeof (setting['func']) == 'undefined' ? key : "onclick=\"" + setting['func'] + "\"";
        param = setting['param'];

        formattertring = fs(linkbutton, [type, icon, text, downarrow, key, func, param]);

        if (setting.RM != 'just')
          string += formattertring;
        if (setting.RM == true || setting.RM == 'just')
          contextMenu += "<li>" + formattertring + "</li>";
        if (setting['separator'] == true) {
          if (setting.RM != 'just')
            string += "<div class=\"separator\"></div>\n\t";
          if (setting.RM == true || setting.RM == 'just')
            contextMenu += "<li class='li_separate'></li>";
        }
      })
      if (contextMenu != '')
        contextMenu = "<div class=__JGcontextMenu id=" + rand() + " style='display: none'><ul>" + contextMenu + " </ul> </div>";

      this.elem.append(contextMenu + string)
    },

    init: function () {
      var that = this,
        elem = that.elem;
    },

    initcontextMenu: function () {
      var grid = this.grid,
        elem = this.elem,
        id = elem.find(".__JGcontextMenu").attr('id');

      if (elem.find(".__JGcontextMenu").length > 0) {
        $(grid).parent().parent().contextMenu(id, {
          //重写onContextMenu和onShowMenu事件
          onContextMenu: function (e) { //显示菜单
            var rowId = $(e.target).closest("tr.jqgrow").attr("id"); //获得RowID 
            grid.jqGrid('resetSelection');
            if (rowId) {

              grid.jqGrid('setSelection', rowId);
            } else {
              var toolbarbotton = elem.find("a");
              toolbarbotton.each(function () {
                var a = $(this);
                var disabeldata = {};
                var options = $.trim(a.attr('data-options'));
                var d;
                ((d = options.substring(0, 1)),
                  (e = options.substring(options.length - 1, 1)),
                  '{' != d && (options = '{' + options),
                  '}' != e && (options += '}'),
                  (disabeldata = new Function('return ' + options)()));
                if (disabeldata.disabled)
                  a.addClass('toolbar-btn-disabled');

              })

            }
            return true;
          },
          onShowMenu: function (e, menu) { //显示菜单

            return menu;
          },
          menuStyle: { //菜单样式			            
            backgroundColor: '#fcfdfd',
            border: '1px solid #a6c9e2',
            maxWidth: '100px', // to be sure 			           
            width: '100%' // to have good width of the menu 			         
          },
          itemHoverStyle: { //点击菜单上面的样式			          
            border: '1px solid #79b7e7',
            color: '#1d5987',
            backgroundColor: '#d0e5f5',

          }

        })
      };
    },
    bindEvent: function (paramelem = '') {
      var that = this,
        grid = that.grid,

        elem = this.elem;
      if (paramelem != '')
        elem = paramelem;
      var isbind = false;


      elem.find('.add').on('click', function () {

        if ($(this).attr('onclick') || grid.length == 0) {
          return;
        }
        var rowid = grid.jqGrid('getGridParam', 'selrow');

        if (rowid) {
          grid.jqGrid('addRow', {
            position: 'after',
            src: rowid
          });
        } else {
          grid.jqGrid('addRow', {
            position: 'last'
          });
        }
      });

      elem.find('.addbatch').on('click', function () {

        if ($(this).attr('onclick') || grid.length == 0) {
          return;
        }
        var rowid = grid.jqGrid('getGridParam', 'selrow');

        for (var i = 0; i < 10; i++) {
          var objectParam = {};
          if (_C_ == 'material') {
            var ids = grid.jqGrid('getDataIDs');

            objectParam = $.extend({}, {
              'name': (ids.length + 1) + '#'
            });
          }

          if (rowid) {
            grid.jqGrid('addRow', {
              position: 'last',
              initdata: objectParam,
              src: rowid
            });
          } else {
            grid.jqGrid('addRow', {
              position: 'last',
              initdata: objectParam
            });
          }
        }
      });

      elem.find('.edit').on('click', function () {

        if ($(this).attr('onclick') || grid.length == 0) {
          return;
        }

        var rowids = grid.jqGrid('getGridParam', 'selarrrow');
        var ids = rowids.length ? rowids : grid.jqGrid('getDataIDs');

        for (var i = 0; i < ids.length; i++) {
          grid.jqGrid('editRow', ids[i]);
        }
      });

      elem.find('.copy').on('click', function () {

        if ($(this).attr('onclick') || grid.length == 0) {
          return;
        }

        var rowid,
          ids = [],
          original,
          rowdata;

        original = grid.jqGrid('getGridParam', 'selarrrow');
        ids = original.concat();

        if (ids.length > 0) {
          rowid = ids[0];
          // 临时保存行,用于获取数据
          grid.jqGrid('saveRow', rowid);

          // 获取行数据
          rowdata = grid.jqGrid('getRowData', rowid);

          grid.jqGrid('resetSelection', rowid);
          delete rowdata.id;

          grid.jqGrid('addRow', {
            initdata: rowdata,
            position: 'after',
            src: rowid
          });
        }
      });


      elem.find('.save').on('click', function () {

        if ($(this).attr('onclick') || grid.length == 0) {
          return;
        }

        var rowids = grid.jqGrid('getDataIDs'),
          editable,
          ind;

        $.each(rowids, function (key, rowid) {
          ind = grid.jqGrid('getInd', rowid, true);
          editable = $(ind).attr('editable') || '0';
          editable === '1' && grid.jqGrid('saveRow', rowid);
        });

        grid.jqGrid('resetSelection');

        that.total(true);
      });

      elem.find('.delete').on('click', function () {

        if ($(this).attr('onclick') || grid.length == 0) {
          return;
        }

        var original = grid.jqGrid('getGridParam', 'selarrrow'),
          ids = original.concat();

        if (ids.length > 0) {
          parent.layer.confirm('确定删除所选行数据吗？', {
            icon: 3,
            title: '提示'
          }, function (index) {
            for (var i = 0; i < ids.length; i++) {
              grid.jqGrid('delRowData', ids[i]);
            }

            that.total(true);
            parent.layer.close(index);
          });
        }
      });

      elem.find('.cog').on('click', function () {

        var param = $(this).attr('data-param') || '[]';
        var args = eval('(' + param + ')');

        var url = sy.url({
          m: 'setting',
          c: 'menu',
          a: 'setGrid',
          param: {
            row: 'fg',
            grid: _M_ + '/' + _C_ + '/' + (args.length > 0 ? args[0] : _A_)
          }
        });

        var opts = {
          title: '修改列配置',
          cancel: true,
          width: 550,
          height: 434,
          ok: function () {
            var f = this.iframe.contentWindow;
            f.document.getElementById('dosubmit').click();
            return false;
          }
        };

        sy.open(url, opts);
      });

      elem.find('.refresh').on('click', function () {

        if ($(this).attr('onclick') || grid.length == 0) {
          return;
        }

        var rowids = grid.jqGrid('getDataIDs'),
          editable,
          ind;

        $.each(rowids, function (key, rowid) {
          ind = grid.jqGrid('getInd', rowid, true);
          editable = $(ind).attr('editable') || '0';
          editable === '1' && grid.jqGrid('restoreRow', rowid);
        });

        grid.jqGrid('resetSelection');
      });

      if (grid.length) {
        grid.jqGrid('setGridParam', {
          ondblClickRow: function (rowid, iRow, iCol, e) {
            grid.jqGrid('editRow', rowid);
          }
        });
      }

      if (typeof ($(this).attr('onclick')) == 'undefined') {
        var that = this,
          elem = this.elem;

        elem.find('.linkbutton,.menu-item').not(".refresh,.cog,.delete,.save,.copy,.edit,.addbatch,.add").on('click', function () {

          var func = $(this).data('func'),
            param = $(this).attr('data-param') || '[]',
            args = eval('(' + param + ')'),
            obj = $(this).closest('div.nr-toolbar').data('toolbaredit');

          // 优化条件，不存在对应方法时，使用默认的dispatch方法
          if (!$(this).hasClass('toolbar-btn-disabled')) {
            if ($.isFunction(obj.funcs[func])) {
              obj.funcs[func].apply(obj, args);
            }
          }
        });
      }
    },
    unbindEvent: function () {
      var that = this,
        grid = that.grid,
        elem = this.elem;

      elem.find('.linkbutton').off('click');
      elem.find('.linkbutton').removeAttr('onclick');

      if (grid.length) {
        grid.jqGrid('setGridParam', {
          ondblClickRow: null
        });
      }
    },

    total: function (callback) {
      var that = this,
        opts = that.options,
        fields;

      if ($.isFunction(opts.loadComplete)) {
        opts.loadComplete.call(that);
      }

      if (opts.totalFields.length == 0) return;

      fields = opts.totalFields || [];
      that.totalData = {};
      total();
      // if (that.timer) {
      //     clearTimeout(that.timer);
      // }
      // that.timer = setTimeout(total, 500);

      function total() {
        var gridDatas = that.grid.jqGrid('getRowData');

        // _.forEach(fields, function(field) {
        //     that.totalData[field] = 0;
        // });

        _.forEach(fields, function (field) {
          if (undefined == that.totalData[field]) {
            that.totalData[field] = 0;
          }
          _.forEach(gridDatas, function (rowdata) {
            that.totalData[field] += pf(rowdata[field]);
          });

          that.totalData[field] = rnf(that.totalData[field]);
        });

        that.grid.jqGrid('footerData', 'set', [that.totalData]);

        if (callback === true) {
          if ($.isFunction(opts.afterTotal)) {
            opts.afterTotal.call(that);
          }
        }
      }
    },
    setFuncs: function (newFunctions) {
      if (typeof newFunctions === 'object') {
        this.funcs = $.extend({}, this.funcs, newFunctions);
      }
    },
    setParam: function (newParams, overwrite) {
      var that = this;

      if (that && typeof newParams === 'object') {
        if (overwrite == null) {
          overwrite = false;
        }
        if (overwrite === false) {
          that.options = $.extend({}, that.options, newParams);
        } else {
          $.extend(true, that.options, newParams);
        }
      }
    },
    addRowData: function (data, trigger, handleData) {
      var that = this,
        opts = that.options,
        value;

      if ($.isFunction(trigger)) {
        handleData = trigger;
        trigger = false;
      }

      for (var i = 0; i < data.length; i++) {
        value = $.isFunction(handleData) ? handleData(data[i]) : data[i];

        if ($.isFunction(opts.beforeAddRowData)) {
          value = opts.beforeAddRowData.call(that, value);
        }

        if ($.isFunction(opts.allowPassed)) {
          if (false === opts.allowPassed.call(that, value)) {
            continue;
          }
        }

        that.grid.jqGrid('addRowData', value.id, value);
      }

      that.total(trigger);
    },
    addRowDataAutoId: function (data, trigger, handleData) {
      var that = this,
        opts = that.options,
        value;

      if ($.isFunction(trigger)) {
        handleData = trigger;
        trigger = false;
      }

      for (var i = 0; i < data.length; i++) {
        value = $.isFunction(handleData) ? handleData(data[i]) : data[i];

        if ($.isFunction(opts.beforeAddRowData)) {
          value = opts.beforeAddRowData.call(that, value);
        }

        if ($.isFunction(opts.allowPassed)) {
          if (false === opts.allowPassed.call(that, value)) {
            continue;
          }
        }

        that.grid.jqGrid('addRowData', $.jgrid.randId(), value);
      }

      that.total(trigger);
    },

    clearRows: function (rowNumber) {
      var that = this,
        grid = that.grid,
        rowdatas = grid.jqGrid('getRowData'),
        number = rowdatas.length,
        row = rowNumber || 1;

      for (var i = 0; i < number; i++) {
        grid.jqGrid('delRowData', rowdatas[i]['id']);
      }

      that.total(true);
    },
    addEmptyRow: function (rowNumber) {
      var that = this,
        grid = that.grid,
        row = rowNumber || 5;

      for (var i = 0; i < row; i++) {
        grid.jqGrid('addRow', {
          position: 'last'
        }).jqGrid('resetSelection');
      }
    },
    destroy: function () {
      var that = this,
        grid = that.grid,
        elem = this.elem;

      elem.find('.linkbutton').addClass('toolbar-btn-disabled');
      that.unbindEvent();
    }
  }
  ToolbarEdit.prototype.funcs = {

    dispatch: function (action, param, callback) {
      var that = this,
        opts = that.options,
        url = sy.url(action, param),
        rowids = that.grid.jqGrid('getGridParam', 'selarrrow');

      if (rowids.length == 0) {
        return sy.alert('请选择要操作的记录!');
      }

      window.setTimeout(function () {
        sy.unmask();
      }, 7000);

      sy.mask('数据正在保存中，请稍等...', 10, true);

      $.ajax({
        url: url,
        type: 'POST',
        dataType: 'json',
        data: {
          'ids[]': rowids
        },
        async: true,
        context: that, // 改变success的this对象
        success: function (data, textStatus, xhr) {
          parent.sy.tip(data.message, data.success);
          if (data.success) {
            this.reloadGrid();

            if ($.isFunction(callback)) {
              callback(data);
            }

            if ($.isFunction(opts.complete)) {
              opts.complete.call(that, data);
            }
          }
        },
        error: function (xhr) {
          sy.responseHandle(xhr);
        },
        complete: function () {
          sy.unmask();
        }
      });
    },
  }
  $.fn.toolbarEdit = function (options) {

    if (typeof options == 'string') {
      var args = arguments,
        toolbar = this.data('toolbaredit'),
        func = toolbar[options];
      Array.prototype.shift.call(args);
      func && func.apply(toolbar, args);
      return this;
    }

    return this.each(function () {
      if (!$.data(this, 'toolbaredit')) {
        $.data(this, 'toolbaredit', new ToolbarEdit(this, options));
      }
    });
  };
  $.fn.toolbarEdit.defaults = {
    totalFields: [],
    afterTotal: null,
    beforeAddRowData: null,
    loadComplete: null,
    allowPassed: null
  };
  $.fn.toolbar = function (options) {
    if (options == null)
      return this.data('toolbar');
    if (typeof options == 'string') {
      var args = arguments,
        toolbar = this.data('toolbar'),
        func = toolbar[options];
      Array.prototype.shift.call(args);
      func && func.apply(toolbar, args);
      return this;
    }

    return this.each(function () {
      if (!$.data(this, 'toolbar')) {
        $.data(this, 'toolbar', new Toolbar(this, options));
        $(window).trigger("resize.grid");
      }
    });
  };

  var Select = function (elem, option, type) {
    this.elem = $(elem);
    this.type = type;
    this.options = $.extend({}, this.defaults, $.fn.select.defaults, option);
    this.init();
  }

  Select.prototype = {
    init: function () {
      var that = this;
      var field = "value";

      var select2 = $("<select style='" + this.options.style + "'>");
      var option = "<option>";
      select2.attr("name", this.options.name);
      select2.addClass(this.options.select);

      $.each(this.options.data, function (k, v) {
        var optionbuf = $(option);
        optionbuf.attr("value", v.id);
        optionbuf.html(v.name);
        if (v.id == that.options.default) {
          optionbuf.attr("selected", "selected");
        }
        select2.append(optionbuf);
      })
      this.elem.append(select2);
      select2.select2(this.type);
    }
  }

  $.fn.select = function (options, type) {

    options = $.extend({}, this.defaults, options);
    return this.each(function () {
      if (!$.data(this, 'select2')) {
        $.data(this, 'select2', new Select(this, options, type));
      }
    });
  }
  $.fn.select.defaults = {
    data: {},
    default: 0,
    select: "select2",
    name: "select2",
    style: "width: 100%;"
  }


  var ZtreeInit = function (elem, option, checkdIds, setting) {
    this.elem = $(elem);
    this.options = option;
    this.setting = $.extend({}, $.fn.ztreeinit.defaults, setting);
    this.checkdIds = checkdIds;
    this.init();
  }

  ZtreeInit.prototype = {
    init: function (checkdIds) {
      var that = this;
      var setting = {
        check: {
          enable: true
        },
        data: {
          simpleData: {
            enable: true
          }
        }
      };

      var zNodes = [];

      $.each(that.options, function (k, v) {
        v.open = true;

        if (that.filterId(v.id)) {
          v.checked = true;
        }
        zNodes[k] = v;
      })

      $(document).ready(function () {
        $.fn.zTree.init(that.elem, that.setting, zNodes);
      })
    },
    filterId: function (id) {
      var res = false;
      $.each(this.checkdIds, function (k, v) {
        if (v == id) {
          res = true;
          return false;
        }
      })
      return res
    }
  }

  $.fn.ztreeinit = function (options, setting, checkdIds = {}, callback = null) {
    options = $.extend({}, this.defaults, options);
    return this.each(function () {
      if (!$.data(this, 'ztreeinit')) {
        $.data(this, 'ztreeinit', new ZtreeInit(this, options, checkdIds, setting));
      }
    });
  }
  $.fn.ztreeinit.defaults = {

    check: {
      enable: true
    },
    data: {
      simpleData: {
        enable: true
      }
    }

  }
  var SubGrid = function (elem, options, subExpandFunction, jqgridid) {
    this.elem = $(elem);
    this.options = $.extend({}, $.subGrid.defaults, options);;
    this.jqgridid = jqgridid;
    this.subExpandFunction = subExpandFunction;

    this.vendor();
    this.init();
  }
  SubGrid.prototype = {
    init: function () {

    },
    vendor: function () {
      var _this = this;
      var options = this.options;
      var pager = false;
      $.each(options.colModel, function (key, value) {
        $.each(value, function (k, v) {

          if (typeof (v) == "string") {
            if (v.substr(0, 1) == "{" || v.substr(0, 8) == "function") {
              options.colModel[key][k] = eval("(" + v + ")");
            } else if (v.substr(0, 10) == "formatter." || v.substr(0, 9) == "unformat.") {
              options.colModel[key][k] = eval("(" + v + ")");
            } else if (k.substr(0, 11) == "editoptions") {
              //修改下拉菜单的时候  使用
              options.colModel[key][k] = eval("(" + v + ")");
              // $columnOption += "\"{$key}\":{value:\"{$val['value']}\"}";
            }
          }
        })

      })

      if (options.pager == true)
        pager = true;
      custom[_this.subExpandFunction] = function (parentRowID, parentRowKey) {

        var url = $("#" + _this.jqgridid).getGridParam("url");
        var childGridID = parentRowID + "_table";
        var childGridPagerID = parentRowID + "_pager";
        var sdiv = "<div class=\"subgrid_table\"><table id=" + childGridID + "></table><div id=" + childGridPagerID + "></div></div>";

        var param = { id: parentRowKey };

        $("#" + parentRowID).append(sdiv);
        $("#" + childGridID).jqGrid({
          url: url,
          postData: param,
          mtype: "POST",
          datatype: "json",
          width: options.width,
          height: options.height,
          pager: pager === true ? "#" + childGridPagerID : "",
          treeGrid: options.treeGrid,
          expandColumn: options.expandColumn,
          treedatatype: "json",
          treeGridModel: "adjacency",
          treeReader: {
            loaded: "loaded",
            icon_field: "icon",
            leaf_field: "isLeaf",
            level_field: "level",
            expanded_field: "expanded",
            parent_id_field: "parentid"
          },
          ExpandColClick: true,
          sortname: options.sortname,
          sortorder: options.sortorder,
          rownumbers: options.rownumbers,
          autowidth: options.autowidth,
          rownumWidth: options.rownumWidth,
          sortable: options.sortable,
          multiselect: options.multiselect,
          multiselectWidth: options.multiselectWidth,
          multiboxonly: options.multiboxonly,
          multikey: options.multikey,
          subGrid: options.subGrid,
          subGridRowExpanded: options.subGridRowExpanded,
          subGridOptions: {
            reloadOnExpand: true,
          },
          shrinkToFit: options.shrinkToFit,
          autoload: options.autoload,
          rowNum: options.rowNum,
          rowList: options.rowList,
          pagerpos: options.pagerpos,
          recordpos: options.recordpos,
          viewrecords: options.viewrecords,
          altRows: options.altRows,
          hoverrows: options.hoverrows,
          colModel: options.colModel,
          toolbar: [false, ""],
          cellEdit: false,
          footerrow: options.footerrow,
          userDataOnFooter: options.userDataOnFooter,
          caption: options.caption,
          onSelectRow: options.onSelectRow || null,
          onSelectAll: options.onSelectAll || null,
          ondblClickRow: options.ondblClickRow || null,
          loadError: function (xhr, status, error) {
            sy.responseHandle(xhr);
          }
        })
          .jqGrid("navGrid", "#" + childGridPagerID, { edit: false, add: false, del: false, search: false, refresh: true });
      }

    }
  };

  $.subGrid = function (options, subExpandFunction = 'subGridRowExpanded', jqgridid = "jqgrid") {
    options = $.extend({}, this.defaults, options);
    return new SubGrid(this, options, subExpandFunction, jqgridid);
  }
  $.subGrid.defaults = {
    'mtype': 'POST',
    'subGrid': false,
    'rownumbers': true, // 是否显示列序号
    'autowidth': true, // 自动宽
    'sortable': true, // 列移动
    'height': 160,
    'width': '100%',
    'rownumWidth': 25, // 列序号宽度
    'multiselectWidth': 25,
    'multiselect': false, // 是否多选
    'multiboxonly': false, // 选中行选中checkbox
    'shrinkToFit': true,
    'autoload': true,
    'sortname': 'id', // 默认的排序列名
    'sortorder': 'desc', // 默认的排序方式（asc升序，desc降序）
    'rowNum': 5, // 每页行数
    'rowList': [5, 10, 20, 40], // 每页行数下拉列表
    'pagerpos': "center",
    'recordpos': "right",
    'viewrecords': false, // 是否在浏览导航栏显示记录总数
    'treeGrid': false,
    'toolbar': [false, 'top'],
    'pager': true,
    'altRows': true, // 设置为交替显示行表格,默认为false
    'hoverrows': true, // 鼠标悬停颜色变化
    'caption': "",
    'expandColumn': "name",
    'footerrow': 0,
    'userDataOnFooter': 1,
    'subGridRowExpanded': null,
    'onSelectRow': null,
    'onSelectAll': null,
    'ondblClickRow': null,
    'colModel': [],
  }

  var Open = function (url, opts) {
    this.model = this.vendor(url, opts);
    this.init();
  }
  Open.prototype = {
    init: function () {

    },
    hidden: function () {
      this.model.modal('hide');
    },
    vendor: function (url, opts) {

      var fatherBody = $(window.top.document.body);
      var model = $("<div class=\"modal fade\" id=\"modal" + Math.random() + "\" style=\"display: none;\" aria-modal=\"true\" role=\"dialog\">" +
        "<div class=\"modal-dialog " + opts.class + "\" style=\" border: 0px none;\">" +
        "<div class=\"modal-content\" ></div></div></div>");

      fatherBody.append(model);
      var content = model.find(".modal-content");
      var header = $("<div class=\"modal-header\"><h4 class=\"modal-title\">" + opts.title + "</h4><button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\"><span aria-hidden=\"true\">×</span> </button></dev>");
      var body = $("<div class=\"modal-body\" ></div>");
      // style=\"min-height:" + opts.height + "px; border: 0px none;\" 
      var iframe = $("<iframe src=" + url + " frameborder=\"0\" allowtransparency=\"true\" style=\"width: 100%; height: 100%; border: 0px none;\" ></iframe>");
      var foot = $("<div class=\"modal-footer justify-content-between\"> </div>");
      body.append(iframe);
      var resizeHeight = function () {
        var height = iframe.contents().height();

        if (opts.height)
          body.height(opts.height);
        else
          body.height(height);

        //减去header，footer，margin
        body.css("max-height", fatherBody.height() - 52 - 54 - 21 + "px");
        console.log("设置高度：" + height + "\n");
        if (height == 0)
          setTimeout(resizeHeight, 200);
      };
      iframe.on("load", function () {

        if (typeof opts.callback == 'function') {
          iframe[0].contentWindow.sy.callback = opts.callback;
        }
        resizeHeight();
        // while (resizeHeight() == 0);
        sy.unmask();
      })
      content.append(header);
      content.append(body);
      content.append(foot);
      if (opts.cancel == true)
        foot.append("<button type=\"button\" class=\"btn btn-default\" data-dismiss=\"modal\">关闭</button>");
      $.each(opts.button, function (k, v) {
        var button = $("<button type=\"button\"  class=\"btn " + v.class + "\">" + v.name + "</button>");
        button.on("click", function (e) {
          v.click(e, iframe);

          if (v.submit === true) {
            sy.mask(content);
            v['model'] = model;
            iframe[0].contentWindow && iframe[0].contentWindow.$('#dosubmit').trigger("ajaxdata", v);
          }
        });
        foot.append(button);
      })
      model.modal().on("hidden.bs.modal", function () {
        $(this).remove();
      }).draggable();
      sy.mask(content);
      return model;
    }
  }
  $.open = function (url, opts) {
    opts = $.extend({}, this.defaults, opts);
    return new Open(url, opts);
  }
  $.open.defaults = {}

  var FormSearch = function (el, opts) {
    this.elem = $(el);
    this.defaults = {
      searchSelector: ".search"
    };
    this.options = $.extend(
      {},
      this.defaults,
      $.fn.formSearch.defaults,
      opts
    );
    this.version = 'v1.0.0';

    this.init();

    // 绑定按钮事件
    this.bindEvent();
    this.setGridParam();
  };

  var _prototype = {
    init: function () {
      var that = this,
        elem = that.elem;

      this.grid = $('#' + (elem.data('grid') || 'jqgrid'));


      that.grid = $('#' + (elem.data('grid') || 'jqgrid'));

      if (!elem.hasClass('nr-form')) {
        console.error('搜索表单缺少类属性(nr-form)');
      }

      if (that.grid.length == 0) {
        console.error('没有找到grid对象');
      }
    },
    bindEvent: function () {
      var that = this,
        opts = that.options,
        grid = that.grid,
        elem = this.elem;

      var dosearch = elem
        .find('#dosearch')
        .off('click')
        .on('click', function () {

          var elem = $(this).closest('.nr-form'),
            formSearch = elem.data('formSearch');
          formSearch.triggerSearch();
        });

      elem.find('#doreset')
        .off('click')
        .on('click', function () {
          var elem = $(this).closest('.nr-form'),
            formSearch = elem.data('formSearch'),
            formDom = $(this)
              .closest('form')
              .get(0);

          formDom.reset();

          elem.find('select').each(function () {
            $(this)
              .val($(this).data('ovalue'))
              .trigger('change.select2');
          });

          elem.find("input[type='hidden']").not('[not-reset]').each(function () {
            var that = $(this);

            if (that.is('[data-value]')) {
              that.val(that.data('value'));
            } else {
              that.val('');
            }
          });

          if (formSearch.grid.data('filterToolbar')) {
            // formSearch.grid.jqGrid('refreshFilterToolbar');
            that.grid.get(0).clearToolbar(false);
          }


          formSearch.triggerSearch();
        });

      if (dosearch.length) {
        // form中只有一个input按回车键表单会自动提交
        $('<input type="text" class="hidden" value=""/>').insertAfter(
          dosearch
        );
      }

      elem.find("input:not(:hidden)").on(
        'keypress',
        function (event) {
          var elem = $(this).closest('.nr-form'),
            formSearch = elem.data('formSearch');
          if (event.keyCode == 13) {
            formSearch.triggerSearch();
            event.preventDefault();
          }
        }
      );

      elem.find("select:not(:disabled)").on(
        'change',
        function () {
          var elem = $(this).closest('.nr-form'),
            formSearch = elem.data('formSearch');
          formSearch.triggerSearch();
        }
      );

      elem.find(":checkbox:not(:disabled)").on(
        'click',
        function () {
          var elem = $(this).closest('.nr-form'),
            formSearch = elem.data('formSearch');
          formSearch.triggerSearch();
        }
      );

      elem.find(":radio:not(:disabled)").on(
        'click',
        function () {
          var elem = $(this).closest('.nr-form'),
            formSearch = elem.data('formSearch');
          formSearch.triggerSearch();
        }
      );
    },
    setGridParam: function () {
      var that = this,
        grid = that.grid;

      if (grid && grid.length) {
        grid.jqGrid('setGridParam', {
          beforeRequest: function () {
            that.storeFormData();
            return true;
          }
        });

        var autoload = grid.jqGrid('getGridParam', 'autoload');
        if (autoload == false) {
          that.triggerSearch();
        }
      }
    },
    unbindEvent: function () {
      var that = this,
        grid = that.grid,
        elem = this.elem;

      elem.find('.linkbutton,.menu-item').off('click');

      if (grid && grid.length) {
        grid.jqGrid('setGridParam', {
          ondblClickRow: null
        });
      }
    },
    storeFormData: function () {
      var that = this,
        elem = that.elem,
        grid = that.grid,
        selector = that.options.searchSelector,
        params = {};

      if (grid.length) {
        elem.find(selector).each(function () {
          if (this.type == 'checkbox') {
            params[this.name] = this.checked ? this.value : '';
          } else if (this.type == 'radio') {
            this.checked && (params[this.name] = this.value);
          } else {
            params[this.name] = $.trim(this.value);
          }
        });

        grid.jqGrid('setGridParam', { postData: params });
      }
    },
    triggerSearch: function () {
      var that = this,
        grid = that.grid,
        gridDom = grid.get(0);

      if (grid.data('filterToolbar')) {
        gridDom.triggerToolbar && gridDom.triggerToolbar();
      } else {
        grid.trigger('reloadGrid', [{ page: 1, datatype: 'json' }]);
      }

      // 重置选中的行数据
      gridDom.p.selarrrow = [];
      gridDom.p.selrow = null;
    },

    getParams: function () {
      var params = {},
        that = this,
        elem = that.elem,
        selector = that.options.searchSelector;

      elem.find(selector).each(function () {
        if (this.type == 'checkbox') {
          params[this.name] = this.checked ? this.value : '';
        } else if (this.type == 'radio') {
          this.checked && (params[this.name] = this.value);
        } else {
          params[this.name] = $.trim(this.value);
        }
      });

      return params;
    },
    reloadGrid: function () {
      this.grid.trigger('reloadGrid', [{ current: true, datatype: 'json' }]);
    }
  };

  _prototype.funcs = {};

  FormSearch.prototype = _prototype;

  $.fn.formSearch = function (options) {
    if (typeof options == 'string') {
      var args = arguments,
        formSearch = this.data('formSearch'),
        func = formSearch[options],
        result;

      Array.prototype.shift.call(args);
      if (func) {
        result = func.apply(formSearch, args);
      }

      this.result = result;
      return this;
    }
    return this.each(function () {
      if (!$.data(this, 'formSearch')) {
        $.data(this, 'formSearch', new FormSearch(this, options));
      }
    });
  };

})(jQuery, window, document);
